home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Copyright 1993, 1994, Cornell University
-
- Cornell hereby grants permission to use, copy, modify, and distribute this program for any purpose
- and without fee, provided that these copyright and permission notices appear on all copies and
- supporting documentation, the name of Cornell not be used in advertising or publicity pertaining
- to distribution of the program without specific prior permission, notice be given in supporting
- documentation that copying and distribution is by permission of Cornell. CORNELL MAKES NO
- REPRESENTATIONS OR WARRANTEES, EXPRESS OR IMPLIED. By way of example, but not limitation,
- CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
- PURPOSE OR THAT THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS,
- TRADEMARKS, OR OTHER RIGHTS. Cornell shall not be held liable for any liability with respect to
- any claim by the user or any other party arising from use of the program.
-
- This material is partially based on work sponsored by the National Science Foundation under Cooperative
- Agreement No. NCR-9318337. The government has certain rights in this material.
-
- */
-
-
-
- #include <stdio.h>
- #include <varargs.h>
- #include <signal.h>
- #include <errno.h>
- #include <malloc.h>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <sys/time.h>
-
- #ifndef LINUX
- #include <sys/socketvar.h>
- #include <net/route.h>
- #endif
-
- #include <net/if.h>
- #include <netinet/in.h>
-
- #include "reflect.h"
- #include "refmon.h"
- #include "rtp.h"
- #include "globals.h"
-
- void write_cmsg(msg,cltptr)
- short msg;
- client *cltptr;
-
- {
- VideoPacketHeader pkt;
-
- pkt.routing.src.family = htons(kReflector);
- bcopy(&myaddr.sin_addr.s_addr,&pkt.routing.src.addr,4);
- pkt.routing.src.addr = 0;
- pkt.routing.src.port = htons(VID_PORT);
-
- pkt.routing.dest.family = htons(kClient);
- bcopy(&cltptr->clnt_addr.addr,&pkt.routing.dest.addr,4);
- pkt.routing.dest.port = htons(VID_PORT);
-
- pkt.seqNum = 0;
- pkt.dataType = htons(kControlType);
- pkt.len = htons(sizeof(VideoPacketHeader));
- pkt.message = htons(msg);
-
- write_pkt(&pkt,cltptr);
- }
-
- void write_close(cltptr,clientIP)
- client *cltptr;
- unsigned long clientIP;
-
- {
- VideoPacketHeader pkt;
- struct in_addr in;
-
- in.s_addr = clientIP;
- dolog("sending a close to client %s on behalf of %s\n",cltptr->clnt_config.name,inet_ntoa(in));
-
- pkt.routing.src.family = htons(kReflector);
- bcopy(&clientIP,&pkt.routing.src.addr,4);
- pkt.routing.src.port = htons(VID_PORT);
-
- pkt.routing.dest.family = htons(kClient);
- bcopy(&cltptr->clnt_addr.addr,&pkt.routing.dest.addr,4);
- pkt.routing.dest.port = htons(VID_PORT);
-
- pkt.seqNum = 0xffffffff;
- pkt.dataType = htons(kConfigVideoType);
- pkt.len = htons(sizeof(VideoPacketHeader));
- pkt.message = htons(kCloseConnection);
-
- write_pkt(&pkt,cltptr);
- }
-
-
-
- void write_pkt(vidptr,cltptr)
- VideoPacketHeader *vidptr;
- client *cltptr;
- {
- struct in_addr in;
-
- if (cltptr->clnt_flags & REF3_ORIGIN)
- cltptr = cltptr->clnt_pptr;
-
- if (cltptr->clnt_flags & HOLD_DOWN)
- return;
-
- #ifdef DEBUG
- if (debug)
- {
- in.s_addr = cltptr->clnt_addr.addr;
- printf("sending to %s\n",inet_ntoa(in));
- }
- #endif
-
- cltptr->clnt_stimer = 0;
-
- pkts_out++;
- bytes_out += ntohs(vidptr->len);
-
- if (sendto(vid_sock,vidptr,ntohs(vidptr->len),0,&cltptr->clnt_addr,sizeof(struct sockaddr_in)) != ntohs(vidptr->len))
- dolog("sendto error %d client %s\n",errno,cltptr->clnt_config.name);
- }
-
-
- write_msg(clnt_addr,type,cptr)
- struct sockaddr_in *clnt_addr;
- short type;
- char *cptr;
- {
- static char buf[MAXMSG];
- VideoPacketHeader *pkt=(VideoPacketHeader *)buf;
- char *tmp,clen;
- short mlen,nlen,cnt;
- int len;
-
- pkt->routing.src.family = htons(kReflector);
- bcopy(&myaddr.sin_addr.s_addr,&pkt->routing.src.addr,4);
- pkt->routing.src.port = htons(VID_PORT);
-
- pkt->routing.dest.family = htons(kClient);
- bcopy(&clnt_addr->sin_addr,&pkt->routing.dest.addr,4);
- pkt->routing.dest.port = htons(VID_PORT);
-
- pkt->seqNum = 0;
- pkt->dataType = htons(type);
- pkt->message = 0;
-
- mlen = strlen(cptr);
-
- for (cnt = 0; cnt < mlen; cnt++)
- {
-
- if (*(cptr+cnt) == '\n')
- *(cptr+cnt) = '\r';
- }
-
- len = sizeof(VideoPacketHeader) + mlen + 2;
-
- pkt->len = htons(len);
-
- tmp = (char *) (pkt+1);
-
- if (type == kMessageType1)
- {
- len--;
- pkt->len = htons(len);
- clen = mlen;
- *tmp = clen;
- bcopy(cptr,(char *)(tmp+1),mlen);
- }
- else
- {
- nlen = htons(mlen);
- bcopy(&nlen,tmp,2);
- bcopy(cptr,(char *)(tmp+2),mlen);
- }
-
- #ifdef DEBUG
- if (debug)
- printf("sending reflector message %s to client at %s\n",cptr,inet_ntoa(clnt_addr->sin_addr));
- #endif
-
- pkts_out++;
- bytes_out += len;
-
- if (sendto(vid_sock,buf,len,0,clnt_addr,sizeof(struct sockaddr_in)) != len)
- {
- dolog("sendto error on old video socket");
- }
- }
-
- void distribute(vidptr,cltptr,all)
- VideoPacketHeader *vidptr;
- client *cltptr;
- char all;
- {
- client *ctmp;
- slist *sptr;
- struct in_addr in;
- int len,cnt;
- short ref_ucast_sent[MAXSRCREF];
- short mcast_sent = FALSE;
-
- cltptr->clnt_hdloop = 0;
- cltptr->clnt_flags &= ~HOLD_DOWN;
-
- if (all == FALSE)
- {
- for (cnt=0; cnt < MAXSRCREF; cnt++)
- ref_ucast_sent[cnt] = 0;
-
- sptr = cltptr->clnt_vlist;
- while (sptr)
- {
- if (sptr->snd_client->clnt_flags & REF3_ORIGIN)
- {
- if ((ctmp = sptr->snd_client->clnt_pptr) == NULL)
- {
- dolog("REF3_ORIGIN client without a parent in distribute\n");
- delete_client(cltptr);
- return;
- }
-
- if ((ctmp->clnt_flags & REF3_SERVER) == 0)
- {
- dolog("REF3_ORIGIN client's parent is not a REF3_SERVER\n");
- delete_client(cltptr);
- return;
- }
-
- if ((ref_ucast_sent[ctmp->clnt_id] == 0) && (cltptr->clnt_flags & REF3_ORIGIN) == 0)
- {
- ref_ucast_sent[ctmp->clnt_id] = 1;
- write_pkt(vidptr,ctmp);
- }
-
- sptr = sptr->snd_nptr;
- continue;
- }
-
- if (sptr->snd_client->clnt_flags & CLIENT)
- write_pkt(vidptr,sptr->snd_client);
-
- sptr = sptr->snd_nptr;
- }
-
- ctmp = chead;
- while (ctmp != NULL)
- {
- if (ctmp->clnt_flags & (BCC_CLIENT | BCC_GCLIENT))
- write_pkt(vidptr,ctmp);
- ctmp = ctmp->clnt_nptr;
- }
-
- /* if necessary, distribute this cu-seeme video packet to all the NV clients */
- if ((cltptr->clnt_flags & (NV_UCLIENT | NV_MCLIENT)) == 0)
- {
- if (nv_out_mcast_sock || nv_inout_mcast_sock || send_to_nv(cltptr))
- nv_wrt(cltptr,vidptr);
- }
- }
- else
- {
- ctmp = chead;
- while (ctmp != NULL)
- {
- if ((ctmp->clnt_flags & CLIENT) && ((self_reflect == 1) || (cltptr != ctmp)))
- write_pkt(vidptr,ctmp);
- else
- if ((ctmp->clnt_flags & REF3_SERVER) && ((cltptr->clnt_flags & (REF3_SERVER | REF3_ORIGIN)) == 0))
- write_pkt(vidptr,ctmp);
- else
- if ((ctmp->clnt_flags & (BCC_CLIENT | BCC_GCLIENT)) && (cltptr != ctmp))
- write_pkt(vidptr,ctmp);
- ctmp = ctmp->clnt_nptr;
- }
- }
-
- #ifdef MULTI
- if (rfout_mcast.sin_addr.s_addr)
- rf_mcast_wrt(vidptr);
-
- if ((cltptr->clnt_flags & (REF2_SERVER | REF2_ORIGIN)) == 0)
- if (inout_mcast.sin_addr.s_addr)
- inout_mcast_wrt(vidptr);
- #endif
- }
-
-
- void distribute_audio(vidptr,cltptr)
- VideoPacketHeader *vidptr;
- client *cltptr;
- {
- client *ctmp;
- unsigned char *cptr,*cptr1;
- vat_client *mtmp;
- slist *sptr;
- struct in_addr in;
- int len,cnt;
- short ref_ucast_sent[MAXSRCREF];
- struct sockaddr_in tmp1;
- vat_hdr_t *vat_hdr;
- unsigned long ul;
- char *tmp;
-
-
- cltptr->clnt_hdloop = 0;
- cltptr->clnt_flags &= ~HOLD_DOWN;
-
- if (cltptr->clnt_talker == 0)
- dolog("%s is speaking\n",cltptr->clnt_config.name);
-
- if (cltptr->clnt_talker++ > 50)
- cltptr->clnt_talker = 0;
-
- if (cltptr->clnt_config.sendMode == 0)
- {
- ctmp = chead;
- while (ctmp != NULL)
- {
- if (ctmp->clnt_flags & CLIENT)
- if ((ctmp->clnt_config.flags & REC_AUDIO) && (ctmp->clnt_config.flags & WANT_LURCKERS))
- write_pkt(vidptr,ctmp);
- ctmp = ctmp->clnt_nptr;
- }
- }
- else
- {
- for (cnt=0; cnt < MAXSRCREF; cnt++)
- ref_ucast_sent[cnt] = 0;
-
- sptr = cltptr->clnt_alist;
- while (sptr)
- {
- if (sptr->snd_client->clnt_flags & REF3_ORIGIN)
- {
- if ((ctmp = sptr->snd_client->clnt_pptr) == NULL)
- {
- dolog("REF3_ORIGIN client without a parent in distribute_audio\n");
- delete_client(cltptr);
- return;
- }
-
- if ((ctmp->clnt_flags & REF3_SERVER) == 0)
- {
- dolog("REF3_ORIGIN client's parent is not a REF3_SERVER\n");
- delete_client(cltptr);
- return;
- }
-
- if ((ref_ucast_sent[ctmp->clnt_id] == 0) && (cltptr->clnt_flags & REF3_ORIGIN) == 0)
- {
- ref_ucast_sent[ctmp->clnt_id] = 1;
- write_pkt(vidptr,ctmp);
- }
-
- sptr = sptr->snd_nptr;
- continue;
- }
-
- if (sptr->snd_client->clnt_flags & CLIENT)
- write_pkt(vidptr,sptr->snd_client);
- sptr = sptr->snd_nptr;
- }
- }
-
- ctmp = chead;
- while (ctmp != NULL)
- {
- if (ctmp->clnt_flags & (BCC_CLIENT | BCC_GCLIENT))
- write_pkt(vidptr,ctmp);
- ctmp = ctmp->clnt_nptr;
- }
-
- #ifdef MULTI
- if (rfout_mcast.sin_addr.s_addr)
- rf_mcast_wrt(vidptr);
-
- if ((cltptr->clnt_flags & (REF2_SERVER | REF2_ORIGIN)) == 0)
- if (inout_mcast.sin_addr.s_addr)
- inout_mcast_wrt(vidptr);
- #endif
-
-
- cptr = ((unsigned char *) vidptr) + HEADERLEN;
- len = vidptr->len - HEADERLEN;
- mtmp = mhead;
-
- if ((mtmp != NULL) || (vat_out_mcast_sock))
- {
- /*
- the following code adds a speaker id to the maven/vat audio
- packet being sent. See vat_hdr_t.
- */
-
- tmp = (char *) cptr;
- tmp -= 4;
-
- bcopy((char *)cptr, tmp, sizeof(vat_hdr_t));
-
- cptr += (sizeof(vat_hdr_t) - 4);
-
- ul = cltptr->clnt_addr.addr;
- cptr1 = (unsigned char *) &ul;
-
- *cptr++ = *cptr1++;
- *cptr++ = *cptr1++;
- *cptr++ = *cptr1++;
- *cptr++ = *cptr1++;
-
- cptr = (unsigned char *) tmp;
-
- vat_hdr = (vat_hdr_t *) cptr;
-
- /* set the number of speaker id's to 1 */
- vat_hdr->nsid = (vat_hdr->nsid & ~NSID_MASK) | 1;
-
- /* set the conference id in this vat audio packet to the vat_confid */
-
- vat_hdr->confid = htons(vat_confid);
-
- len += 4;
-
- while (mtmp != NULL)
- {
- if ((mtmp->mvn_recv_type == UCAST) && ((mtmp->mvn_flags & VAT_MIXER_CLIENT) == 0))
- #ifdef DEBUG
- if (debug)
- {
- in.s_addr = mtmp->mvn_addr.addr;
- printf("reflecting CUSEEME audio to ucast maven %s \n", inet_ntoa(in));
- }
- #endif
- if (sendto(maven_sock,cptr,len,0,&mtmp->mvn_addr,sizeof(struct sockaddr_in)) != len)
- dolog("maven sendto error in distribute\n");
-
- mtmp = mtmp->mvn_nptr;
- }
-
- tmp1.sin_family = AF_INET;
- tmp1.sin_addr.s_addr = htonl(vat_out_mcast.sin_addr.s_addr);
- tmp1.sin_port = htons(vat_port);
-
- /*
- if there are any mcast clients then we want to distribute this audio
- to them if vat_inout_mcast_sock has been bound...
- */
-
- if (num_vat_clients(MCAST))
- {
- if (vat_inout_mcast_sock)
- {
- if (sendto(vat_inout_mcast_sock,cptr,len,0,&tmp1,sizeof(struct sockaddr_in)) != len)
- dolog("mcast sendto error");
- }
- }
- else
- if (vat_out_mcast_sock)
- {
- /*
- else, (ie if there are no mcast vat/maven clients) if vat_out_mcast_sock
- has been bound, blindly send this vat stream onto the mcast address
- */
-
- if (sendto(vat_out_mcast_sock,cptr,len,0,&tmp1,sizeof(struct sockaddr_in)) != len)
- dolog("mcast sendto error");
- }
- }
- }
-
-
- void distribute_aux(vidptr,cltptr)
- VideoPacketHeader *vidptr;
- client *cltptr;
- {
- client *ctmp;
- slist *sptr;
- unsigned char *aux;
- struct in_addr in;
- int len,cnt;
- unsigned long aux_mask;
- short ref_ucast_sent[MAXSRCREF];
- char tmp[100];
-
- aux = (unsigned char *) ((char *)vidptr+HEADERLEN+4);
- bcopy(aux,&aux_mask,4);
- aux_mask = ntohl(aux_mask);
- dolog("AUX data packet mask is %ld\n",aux_mask);
- cltptr->clnt_hdloop = 0;
- cltptr->clnt_flags &= ~HOLD_DOWN;
-
- for (cnt=0; cnt < MAXSRCREF; cnt++)
- ref_ucast_sent[cnt] = 0;
-
- sptr = cltptr->clnt_xlist;
- while (sptr)
- {
- if ((sptr->snd_auxmask & aux_mask) != 0)
- {
- if (sptr->snd_client->clnt_flags & REF3_ORIGIN)
- {
- if ((ctmp = sptr->snd_client->clnt_pptr) == NULL)
- {
- dolog("REF3_ORIGIN client without a parent in distribute\n");
- delete_client(cltptr);
- return;
- }
-
- if ((ctmp->clnt_flags & REF3_SERVER) == 0)
- {
- dolog("REF3_ORIGIN client's parent is not a REF3_SERVER\n");
- delete_client(cltptr);
- return;
- }
-
- if ((ref_ucast_sent[ctmp->clnt_id] == 0) && (cltptr->clnt_flags & REF3_ORIGIN) == 0)
- {
- ref_ucast_sent[ctmp->clnt_id] = 1;
- write_pkt(vidptr,ctmp);
- }
-
- sptr = sptr->snd_nptr;
- continue;
- }
-
- if (sptr->snd_client->clnt_flags & CLIENT)
- {
- in.s_addr = vidptr->routing.src.addr;
- sprintf(tmp,"sending AUX data from %s ",inet_ntoa(in));
- in.s_addr = sptr->snd_client->clnt_addr.addr;
- dolog("%s to %s\n",tmp,inet_ntoa(in));
- write_pkt(vidptr,sptr->snd_client);
- }
- }
- sptr = sptr->snd_nptr;
- }
-
- ctmp = chead;
- while (ctmp != NULL)
- {
- if (ctmp->clnt_flags & (BCC_CLIENT | BCC_GCLIENT))
- write_pkt(vidptr,ctmp);
- ctmp = ctmp->clnt_nptr;
- }
-
- #ifdef MULTI
- if (rfout_mcast.sin_addr.s_addr)
- rf_mcast_wrt(vidptr);
-
- if ((cltptr->clnt_flags & (REF2_SERVER | REF2_ORIGIN)) == 0)
- if (inout_mcast.sin_addr.s_addr)
- inout_mcast_wrt(vidptr);
- #endif
- }
-
-
- /* distribute nv video to other nv's */
-
- void distribute_nv(rtp_hdr_ptr,msglen,nvcptr)
- struct rtphdr **rtp_hdr_ptr;
- int *msglen;
- client *nvcptr;
-
- {
- struct rtpopthdr *optr;
- struct rtpssrchdr *sptr;
- client *ctmp;
- short err,len;
- char *cptr;
-
- cptr = (char *) (*rtp_hdr_ptr + 1);
-
- if ((*rtp_hdr_ptr)->rh_opts)
- {
- optr = (struct rtpopthdr *) cptr;
-
- if (!optr->roh_fin)
- {
- dolog("In distribute_nv, received rtp packet with more then one option\n");
- return;
- }
- optr->roh_fin = 0;
- cptr += 4*(optr->roh_optlen);
- }
-
- (*rtp_hdr_ptr)->rh_opts = 1;
-
- len = cptr - (char *) *rtp_hdr_ptr;
- bcopy((char *)*rtp_hdr_ptr,(char *)*rtp_hdr_ptr - sizeof(struct rtpssrchdr),len);
-
- *rtp_hdr_ptr = (struct rtphdr *) ((char *) *rtp_hdr_ptr - sizeof(struct rtpssrchdr));
-
- sptr = (struct rtpssrchdr *) ((char *) *rtp_hdr_ptr + len);
-
- sptr->rsh_fin = 1;
- sptr->rsh_type = RTPOPT_SSRC;
- sptr->rsh_optlen = 2;
- sptr->rsh_id = htons(nvcptr->clnt_id);
- sptr->rsh_addr = htonl(nvcptr->clnt_addr.addr);
-
- *msglen += sizeof(struct rtpssrchdr);
-
- ctmp = chead;
- while (ctmp != NULL)
- {
- if ((ctmp->clnt_flags & NV_UCLIENT) && (ctmp != nvcptr))
- if (err = (sendto(nv_ucast_sock,*rtp_hdr_ptr,*msglen,0,&ctmp->clnt_addr,sizeof(struct sockaddr_in))) != *msglen)
- dolog("ucast nv->nv sendto error %d\n",err);
-
- ctmp = ctmp->clnt_nptr;
- }
-
- if ((nvcptr->clnt_flags & NV_MCLIENT) == 0)
- {
- if (nv_out_mcast_sock)
- {
- if (err = (sendto(nv_out_mcast_sock,*rtp_hdr_ptr,*msglen,0,&nv_out_mcast,sizeof(struct sockaddr_in))) != *msglen)
- dolog("mcast nv->nv sendto error %d\n",err);
- }
-
- if (nv_inout_mcast_sock)
- {
- if (err = (sendto(nv_inout_mcast_sock,*rtp_hdr_ptr,*msglen,0,&nv_inout_mcast,sizeof(struct sockaddr_in))) != *msglen)
- dolog("mcast nv->nv sendto error %d\n",err);
- }
- }
- }
-
-
- /*
- void distribute_nv(msg,msglen,nvcptr)
- unsigned char *msg;
- int msglen;
- client *nvcptr;
-
- {
- client *ctmp;
- short err;
-
- ctmp = chead;
- while (ctmp != NULL)
- {
- if ((ctmp->clnt_flags & NV_UCLIENT) && (ctmp != nvcptr))
- if (err = (sendto(nv_ucast_sock,msg,msglen,0,&ctmp->clnt_addr,sizeof(struct sockaddr_in))) != msglen)
- dolog("ucast nv->nv sendto error %d\n",err);
-
- ctmp = ctmp->clnt_nptr;
- }
-
- if ((nvcptr->clnt_flags & NV_MCLIENT) == 0)
- {
- if (nv_out_mcast_sock)
- {
- if (err = (sendto(nv_out_mcast_sock,msg,msglen,0,&nv_out_mcast,sizeof(struct sockaddr_in))) != msglen)
- dolog("mcast nv->nv sendto error %d\n",err);
- }
-
- if (nv_inout_mcast_sock)
- {
- if (err = (sendto(nv_inout_mcast_sock,msg,msglen,0,&nv_inout_mcast,sizeof(struct sockaddr_in))) != msglen)
- dolog("mcast nv->nv sendto error %d\n",err);
- }
- }
- }
- */
-